package api

import (
	"errors"
	"fmt"
	"github.com/gin-gonic/gin"
	"github.com/sirupsen/logrus"
	"github.com/spf13/cast"
	"hc_server/pkg/app"
	pkgFile "hc_server/pkg/file"
	"hc_server/routers/service/user"
	"hc_server/runtime/e"
	"mime/multipart"
	"os"
	"path"
	"path/filepath"
)

// @Summary Import Image
// @Produce  json
// @Param image formData file true "Image File"
// @Success 200 {object} app.Response
// @Failure 500 {object} app.Response
// @Router /api/v1/tags/import [post]

func UploadImage(c *gin.Context) {
	appG := app.Gin{C: c}
	file, image, err := c.Request.FormFile("image")
	userId := c.PostForm("userId")
	typed := c.PostForm("type") // 1=上传用户头像

	userService := user.User{ID: cast.ToInt(userId)}

	if err != nil {
		logrus.Warn(err)
		logrus.Info(fmt.Sprintf("UploadImage userId:%s err:%v", userId, err))
		appG.ResponseError(e.CodeMap[e.ERROR], nil)
		return
	}

	if userService.ID == 0 {
		logrus.Info(fmt.Sprintf("UploadImage userId:%s err:%v 缺少参数userId", userId, err))
		appG.ResponseError("缺少参数userId", nil)
		return
	}

	if len(typed) == 0 {
		logrus.Info(fmt.Sprintf("UploadImage userId:%s err:%v 缺少参数type", userId, err))
		appG.ResponseError("缺少参数userId", nil)
		return
	}

	exist, err := userService.ExistByID()
	if err != nil {
		logrus.Error(fmt.Sprintf("UploadImage 此用户不存在 userService:%v err:%s", userService, err.Error()))
		appG.ResponseError("此用户不存在", nil)
		return
	}

	if !exist {
		logrus.Error(fmt.Sprintf("UploadImage 此用户不存在 userService:%v", userService))
		appG.ResponseError("此用户不存在", nil)
		return
	}

	_, fileUrl, err := VerifyFile(file, image, c, userId, "")
	if err != nil {
		appG.ResponseError(err.Error(), nil)
		return
	}

	err = UploadImageType(userId, cast.ToInt(typed), fileUrl)
	if err != nil {
		logrus.Info(fmt.Sprintf("UploadImage userId:%s err:%v msg:%s", userId, err, e.CodeMap[e.ERROR_UPLOAD_FAIL]))
		appG.ResponseError(err.Error(), nil)
		return
	}

	appG.ResponseSuccess("上传成功", map[string]string{
		"image_url": fileUrl,
	})
}

func UploadImageType(userId string, typed int, path string) error {
	switch typed {
	case 1:
		//修改用户头像
		userService := user.User{ID: cast.ToInt(userId), Avatar: path}
		err := userService.EditUserAvatar()
		if err != nil {
			return err
		}
	}

	return nil
}

func VerifyFile(file multipart.File, image *multipart.FileHeader, c *gin.Context, userId, fileName string) (string, string, error) {
	if image == nil {
		logrus.Info(fmt.Sprintf("UploadImage userId:%s msg:%s", userId, e.CodeMap[e.INVALID_PARAMS]))
		return "", "", errors.New(e.CodeMap[e.INVALID_PARAMS])
	}
	if len(fileName) == 0 {
		fileName = pkgFile.GetImageName(image.Filename)
	}

	fullPath := pkgFile.GetFileFullPath()
	ext := path.Ext(fileName)
	if len(ext) == 0 {
		fileName = fileName + ".jpg"
	}

	var src string
	if len(userId) == 0 {
		src = fullPath + fileName
	} else {
		src = fullPath + userId + "/" + fileName

		err := os.MkdirAll(fullPath+userId+"/", os.ModePerm)
		if err != nil {
			logrus.Info(fmt.Sprintf("UploadImage 创建文件夹失败 userId:%s err:%v ", userId, err))
			return "", "", errors.New("创建文件夹失败")
		}
	}

	if !pkgFile.CheckImageExt(fileName) || !pkgFile.CheckImageSize(file) {
		logrus.Info(fmt.Sprintf("UploadImage userId:%s msg:%s", userId, e.CodeMap[e.ERROR_UPLOAD_CHECK_IMAGE_FORMAT]))
		return "", "", errors.New(e.CodeMap[e.ERROR_UPLOAD_CHECK_IMAGE_FORMAT])
	}

	err := pkgFile.CheckImage(fullPath)
	if err != nil {
		logrus.Warn(err)
		logrus.Info(fmt.Sprintf("UploadImage userId:%s err:%v msg:%s", userId, err, e.CodeMap[e.ERROR_UPLOAD_CHECK_IMAGE_FAIL]))
		return "", "", errors.New(e.CodeMap[e.ERROR_UPLOAD_CHECK_IMAGE_FAIL])
	}

	if err = c.SaveUploadedFile(image, src); err != nil {
		logrus.Warn(err)
		logrus.Info(fmt.Sprintf("UploadImage userId:%s err:%v msg:%s", userId, err, e.CodeMap[e.ERROR_UPLOAD_SAVE_IMAGE_FAIL]))
		return "", "", errors.New(e.CodeMap[e.ERROR_UPLOAD_SAVE_IMAGE_FAIL])
	}
	fileUrl := pkgFile.GetImageFullUrl(fileName, userId)
	return fileName, fileUrl, nil
}

// VerifyFileAndSave 验证文件并保存
func VerifyFileAndSave(c *gin.Context, paramName, customName, id string) (string, error) {
	if len(customName) == 0 {
		return "", errors.New("请输入fileName")
	}

	file, img, err := c.Request.FormFile(paramName) //经营场所照片
	if err != nil || img.Size == 0 {
		logrus.WithError(err).Errorf("上传文件失败:%v", err)
		return "", errors.New("上传文件失败")
	}
	if len(path.Ext(img.Filename)) == 0 {
		return "", errors.New("上传文件缺少后缀名")
	}

	var tempName string
	if len(customName) > 0 {
		tempName = customName
	} else {
		tempName = paramName
	}

	fullName := tempName + path.Ext(img.Filename)

	_, _, err = VerifyFile(file, img, c, id, fullName)
	if err != nil {
		return "", err
	}
	return fullName, nil
}

// MoveDirTempToUser 把文件从临时空间移动到用户的文件夹
func MoveDirTempToUser(userId string, fileName string) error {
	source := pkgFile.GetFileFullPath() + fileName
	target := pkgFile.GetFileFullPath() + userId + "/" + fileName

	err := os.MkdirAll(filepath.Dir(pkgFile.GetFileFullPath()+userId+"/"), os.ModePerm)
	if err != nil {
		return err
	}

	err = os.Rename(source, target)
	if err != nil {
		fmt.Println(err)
		return err
	}

	return nil
}
